﻿using pcEntity;
using pcObjectLibrary;
using System;
using System.Collections.Generic;
using System.Linq;
using Omu.ValueInjecter;
using System.Web.Mvc;

namespace pcDAL
{
    public class UserDAL
    {

        public UserObjLibrary Details(string userName)
        {
            UserObjLibrary user = new UserObjLibrary();
            using (var context = new PunchClockEntities())
            {
                var _user = (from u in context.tUsers
                             where u.userName.ToLower() == userName.ToLower()
                             select u).FirstOrDefault();
                if (_user != null)
                    user.InjectFrom(_user);
                user.lastPunch = (from p in context.tPunches
                                  where p.userId == _user.userId
                                  orderby p.punchDate descending
                                  select new PunchObjectLibrary
                                  {
                                      punchId = p.punchId,
                                      punchDate = p.punchDate,
                                      punchIn = p.punchIn,
                                      punchOut = p.punchOut
                                  }).Take(1).FirstOrDefault();
            }
            return user;
        }

        public UserObjLibrary Details(int userId)
        {
            UserObjLibrary user = new UserObjLibrary();
            using (var context = new PunchClockEntities())
            {
                var _user = (from u in context.tUsers
                             where u.userId == userId
                             select u).FirstOrDefault();
                if (_user != null)
                    user.InjectFrom(_user);
                user.lastPunch = (from p in context.tPunches
                                  where p.userId == _user.userId
                                  orderby p.punchDate descending
                                  select new PunchObjectLibrary
                                  {
                                      punchId = p.punchId,
                                      punchDate = p.punchDate,
                                      punchIn = p.punchIn,
                                      punchOut = p.punchOut
                                  }).Take(1).FirstOrDefault();
            }
            return user;
        }

        public int Add(UserObjLibrary user)
        {
            tUser u = new tUser();
            u.InjectFrom(user);
            u.globalId = Guid.NewGuid();
            u.dateCreated_utc = DateTime.UtcNow;
            u.lastActivityDate_utc = DateTime.UtcNow;
            u.isActive = true;
            u.isAdmin = null;
            u.isDeleted = false;
            u.passwordDisabled = false;
            using (PunchClockEntities context = new PunchClockEntities())
            {
                var company = context.tCompanies.Where(c => c.registerCode.Equals(user.registrationCode)).FirstOrDefault();
                //check if user name is already existing
                if (context.tUsers.Where(x => x.userName.ToLower().Equals(user.userName.ToLower())).Count() > 0)
                {
                    u.userId = (int)RegistrationStatusEnum.UserNameNotAvailable;
                }
                else if (company == null)
                {
                    // invalid registration code
                    u.userId = (int)RegistrationStatusEnum.InvalidRegistrationCode;
                }
                else // insert only if user name is not existing
                {
                    u.companyId = company.companyId;
                    // A manual check is required for manager accounts
                    if (u.userTypeId ==  (int)UserTypesEnum.Manager)
                        u.isActive = false;
                    context.tUsers.Add(u);
                    context.SaveChanges();
                }
            }
            return u.userId;
        }

        public int Update(UserObjLibrary user, bool adminUpdate)
        {
            tUser u = new tUser();
            using (PunchClockEntities context = new PunchClockEntities())
            {
                u = context.tUsers.Where(x => x.userId == user.userId).FirstOrDefault();
                u.firstName = user.firstName;
                u.lastName = user.lastName;
                u.middleName = user.middleName;
                u.email = user.email;
                u.telephone = user.telephone;
                if (!adminUpdate)
                {
                    u.lastActive_MAC_address = user.lastActive_MAC_address;
                    u.lastActivity_ip = user.lastActivity_ip;
                    u.lastActivityDate_utc = DateTime.UtcNow;
                }
                else
                {
                    u.registeredTimeZone = user.registeredTimeZone;
                    if (user.userTypeId > 0)
                        u.userTypeId = user.userTypeId;
                    if (user.EmploymentTypeId> 0)
                        u.EmploymentTypeId = user.EmploymentTypeId;
                }
                u.lastUpdated_utc = DateTime.UtcNow;
                context.SaveChanges();
            }
            return user.userId;
        }

        public int LogInActivity(UserObjLibrary user)
        {
            tUser u = new tUser();
            using (PunchClockEntities context = new PunchClockEntities())
            {
                u = context.tUsers.Where(x => x.userId == user.userId).FirstOrDefault();
                u.lastActive_MAC_address = user.lastActive_MAC_address;
                u.lastActivity_ip = user.lastActivity_ip;
                u.lastActivityDate_utc = DateTime.UtcNow;
                context.SaveChanges();
            }
            return user.userId;
        }


        public int UpdatePassword(UserObjLibrary user)
        {
            tUser u = new tUser();
            using (PunchClockEntities context = new PunchClockEntities())
            {
                u = context.tUsers.Where(x => x.userId == user.userId).FirstOrDefault();
                u.passwordLastChanged = DateTime.UtcNow;
                u.passwordHash = user.passwordHash;
                u.lastActive_MAC_address = user.lastActive_MAC_address;
                u.lastActivity_ip = user.lastActivity_ip;
                u.lastActivityDate_utc = DateTime.UtcNow;
                u.lastUpdated_utc = DateTime.UtcNow;
                context.SaveChanges();
            }
            return user.userId;
        }

        public string getTimeZoneOfUser(int userId)
        {
            string retTimeZone = null;
            using (PunchClockEntities context = new PunchClockEntities())
            {
                retTimeZone = context.tUsers.Where(x => x.userId == userId).Select(x => x.registeredTimeZone).FirstOrDefault();
            }
            return retTimeZone;
        }

        public List<SelectListItem> GetAllCompanyEmployees(int companyId, int opUserTypeId)
        {
            List<SelectListItem> employees = new List<SelectListItem>();
            using (PunchClockEntities context = new PunchClockEntities())
            {
                var _employees = (from u in context.tUsers
                             where u.companyId == companyId
                             //&& u.userTypeId == (int)userTypesEnum.Employee
                             select new UserObjLibrary
                             {
                                 userId = u.userId,
                                 firstName = u.firstName,
                                 lastName = u.lastName,
                                 middleName = u.middleName
                             }).ToList();
                if (opUserTypeId == (int)UserTypesEnum.CompanyAdmin || opUserTypeId == (int)UserTypesEnum.Admin)
                    employees = (from e in _employees select new SelectListItem { Text = string.Format("{0} {1} {2}", e.firstName, e.middleName, e.lastName), Value = string.Format("{0}", e.userId) }).ToList();
                else
                    employees = (from e in _employees where e.userTypeId != (int)UserTypesEnum.CompanyAdmin && e.userTypeId != (int)UserTypesEnum.Admin select new SelectListItem { Text = string.Format("{0} {1} {2}", e.firstName, e.middleName, e.lastName), Value = string.Format("{0}", e.userId) }).ToList();
            }
            return employees;
        }



        public List<HolidaysObjLibrary> GetCompanyHolidays(int companyId, int userId, DateTime stDate, DateTime enDate)
        {
            var intime =new TimeSpan(09, 00, 00);
            var outTime = new TimeSpan(17, 00, 00);

            List<HolidaysObjLibrary> holidays = new List<HolidaysObjLibrary>();
            using (PunchClockEntities context = new PunchClockEntities())
            {
                holidays = (from h in context.usp_GetCompanyHolidaysForEmployee(companyId: companyId, employeeId: userId).ToList()
                            select new HolidaysObjLibrary
                            {
                                HolidayDate = h.HolidayDate,
                                HolidayName = h.HolidayName,
                                punchIn = intime,
                                punchOut = outTime,
                                Hours = (int)outTime.Subtract(intime).TotalSeconds
                            }).ToList();
            }
            return holidays;
        }

        public List<UserObjLibrary> GetAllUsers(int companyId)
        {
            List<UserObjLibrary> users = new List<UserObjLibrary>();
            using (PunchClockEntities context = new PunchClockEntities())
            {
                users = (from u in context.tUsers
                         where u.companyId == companyId
                         select new UserObjLibrary
                         {
                             companyId = u.companyId,
                             dateCreated_utc = u.dateCreated_utc,
                             email = u.email,
                             EmploymentTypeId = u.EmploymentTypeId,
                             firstName = u.firstName,
                             globalId = u.globalId,
                             isActive = u.isActive,
                             isAdmin = u.isAdmin,
                             isDeleted = u.isDeleted,
                             lastActive_MAC_address = u.lastActive_MAC_address,
                             lastActivity_ip = u.lastActivity_ip,
                             lastActivityDate_utc = u.lastActivityDate_utc,
                             lastName = u.lastName,
                             lastUpdated_utc = u.lastUpdated_utc,
                             middleName = u.middleName,
                             registered_MAC_address = u.registered_MAC_address,
                             registeredTimeZone = u.registeredTimeZone,
                             userId = u.userId,
                             userName = u.userName,
                             userRegistered_ip = u.userRegistered_ip,
                             userTypeId = u.userTypeId
                         }).ToList();
            }
            return users;
        }
    }
}
